index.ts ➔ getCurrentDate   A
last analyzed

Complexity

Conditions 1

Size

Total Lines 3
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
import * as core from '@actions/core';
2
import {Octokit} from '@octokit/rest';
3
import {config} from 'dotenv';
4
import {resolve} from 'path';
5
import * as chromeLauncher from 'chrome-launcher';
6
import * as lighthouse from 'lighthouse';
7
import {Flags} from 'lighthouse/types/externs';
8
9
// Load environment variables
10
config({path: resolve(__dirname, '../.env')});
11
12
interface ActionInputs {
13
  GH_TOKEN: string;
14
  GIST_ID: string;
15
  TEST_URL: string;
16
  PRINT_SUMMARY: boolean;
17
  RESULT_BADGE: boolean;
18
}
19
20
const ACTION_URL = 'https://github.com/marketplace/actions/lighthouse-box';
21
const inputs: ActionInputs = {
22
  GH_TOKEN: core.getInput('GH_TOKEN', {required: true}),
23
  GIST_ID: core.getInput('GIST_ID', {required: true}),
24
  TEST_URL: core.getInput('TEST_URL', {required: true}),
25
  PRINT_SUMMARY: core.getBooleanInput('PRINT_SUMMARY', {required: true}),
26
  RESULT_BADGE: core.getBooleanInput('RESULT_BADGE', {required: true}),
27
};
28
29
function getCurrentDate(): string {
30
  return new Date().toLocaleDateString('en-us', {day: 'numeric', year: 'numeric', month: 'short'});
31
}
32
33
const UPDATE_DATE: string = getCurrentDate();
34
const summaryTable: any[] = [];
35
const GIST_TITLE = `My website [update ${UPDATE_DATE}]`;
36
37
async function fetchMetrics(testUrl: string): Promise<lighthouse.RunnerResult> {
38
  const chrome = await chromeLauncher.launch({chromeFlags: ['--headless']});
39
  const OPTIONS: Flags = {logLevel: 'info', output: 'json', port: chrome.port};
40
  const runnerResult = await lighthouse(testUrl, OPTIONS);
41
  await chrome.kill();
42
  return runnerResult;
43
}
44
45
function generateGistContent(runnerResult: lighthouse.RunnerResult): string {
46
  const {categories} = runnerResult.lhr;
47
  const metrics = {
48
    performance: categories.performance.score * 100,
49
    accessibility: categories.accessibility.score * 100,
50
    bestPractices: categories['best-practices'].score * 100,
51
    seo: categories.seo.score * 100,
52
    pwa: categories.pwa.score * 100,
53
  };
54
  summaryTable.push([{data: 'Category', header: true}, {data: 'Result', header: true}]);
55
  return Object.entries(metrics).map(([category, score]) => {
56
    summaryTable.push([category, `${score}%`]);
57
    let badge = '🙉';
58
    if (score > 80) badge = '🥈';
59
    if (score > 90) badge = '🥇';
60
    if (score === 100) badge = '🏆';
61
    const title = `${category}:`.padEnd(inputs.RESULT_BADGE ? 37 : 49, '.');
62
    const percent = `${score}%`.padStart(4, '.');
63
    const result = inputs.RESULT_BADGE ? ` ${badge}`.padStart(11, '.') : '';
64
    return `${title}${percent}${result}`;
65
  }).join('\n');
66
}
67
68
async function updateGistContent(gistId: string, content: string): Promise<void> {
69
  const octokit = new Octokit({auth: inputs.GH_TOKEN});
70
  try {
71
    const gist = await octokit.gists.get({gist_id: gistId});
72
    const filename = Object.keys(gist.data.files || {})[0];
73
    if (!filename) {
74
      core.setFailed('Action failed: Gist filename not found');
75
      return;
76
    }
77
    await octokit.gists.update({
78
      gist_id: gistId,
79
      files: {[filename]: {filename: GIST_TITLE, content}},
80
    });
81
  } catch (error: any) {
82
    core.setFailed(`Action failed: Gist ${error.message}`);
83
  }
84
}
85
86
async function printLighthouseSummary(runnerResult: lighthouse.RunnerResult): Promise<void> {
87
  const summary = core.summary
88
    .addHeading('Results')
89
    .addTable(summaryTable)
90
    .addBreak()
91
    .addRaw('Lighthouse metrics for ')
92
    .addLink(runnerResult.lhr.mainDocumentUrl, runnerResult.lhr.mainDocumentUrl)
93
    .addRaw(' generated by ')
94
    .addLink('lighthouse-box/1.1', ACTION_URL);
95
  if (inputs.PRINT_SUMMARY) {
96
    await summary.write();
97
  } else {
98
    console.log(summary.stringify());
99
  }
100
}
101
102
(async () => {
103
  const runnerResult = await fetchMetrics(inputs.TEST_URL);
104
  const gistContent = generateGistContent(runnerResult);
105
  await updateGistContent(inputs.GIST_ID, gistContent);
106
  await printLighthouseSummary(runnerResult);
107
})();
108